package com.qf.kdxf.service.impl;

import com.google.gson.Gson;
import com.qf.kdxf.entity.speechsynthesis.JsonParse;
import com.qf.kdxf.entity.speechsynthesis.SpeechEntity;
import com.qf.kdxf.service.SpeechSynthesisService;
import okhttp3.HttpUrl;
import org.java_websocket.WebSocket;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.springframework.stereotype.Service;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class SpeechSynthesisServiceImpl implements SpeechSynthesisService {
    public static final String hostUrl = "接口地址";
    // 均到控制台-语音合成页面获取
    public static final String APPID = "你的应用APPID";
    public static final String APISecret = "你的APISecret";
    public static final String APIKey = "你的APIKey";
    // json
    public Gson gson = new Gson();
    public boolean wsCloseFlag = false;
    /**
     * todo:4.建立websocket链接
     */
    // Websocket方法
    @Override
    public void websocketWork(SpeechEntity speechEntity) {
        try {
            URI uri = new URI(speechEntity.getWsUrl());

            WebSocketClient webSocketClient = new WebSocketClient(uri) {
                /**
                 * todo:5.将客户端数据发给服务端
                 * @param serverHandshake
                 */
                @Override
                public void onOpen(ServerHandshake serverHandshake) {
                    System.out.println("ws建立连接成功...");
                }
                /**
                 * todo:6.将服务端返回数据进行解析
                 * @param text
                 */
                @Override
                public void onMessage(String text) {
                    System.out.println(text);
                    JsonParse myJsonParse = gson.fromJson(text, JsonParse.class);
                    if (myJsonParse.getCode() != 0) {
                        System.out.println("发生错误，错误码为：" + myJsonParse.getCode());
                        System.out.println("本次请求的sid为：" + myJsonParse.getSid());
                    }
                    if (myJsonParse.getData() != null) {
                        try {
                            byte[] textBase64Decode = Base64.getDecoder().decode(myJsonParse.getData().getAudio());
                            speechEntity.getOutput_file_path().write(textBase64Decode);
                            speechEntity.getOutput_file_path().flush();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (myJsonParse.getData().getStatus() == 2) {
                            try {
                                speechEntity.getOutput_file_path().close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            System.out.println("本次请求的sid==>" + myJsonParse.getSid());
                            // 可以关闭连接，释放资源
                            wsCloseFlag = true;
                        }
                    }
                }

                @Override
                public void onClose(int i, String s, boolean b) {
                    System.out.println("ws链接已关闭，本次请求完成...");
                }

                @Override
                public void onError(Exception e) {
                    System.out.println("发生错误 " + e.getMessage());
                }
            };
            // 建立连接
            webSocketClient.connect();
            while (!webSocketClient.getReadyState().equals(WebSocket.READYSTATE.OPEN)) {
                System.out.println("正在连接...");
                Thread.sleep(100);
            }
            sendVoid(webSocketClient, speechEntity);

        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
    //自定义发送音频参数方法
    public  void sendVoid(WebSocketClient webSocketClient,SpeechEntity speechEntity) {
        String requestJson;//请求参数json串
        requestJson = "{\n" +
                "  \"common\": {\n" +
                "    \"app_id\": \"" + APPID + "\"\n" +
                "  },\n" +
                "  \"business\": {\n" +
                "    \"aue\": \"lame\",\n" +
                "    \"sfl\": 1,\n" +
                "    \"tte\": \"" + speechEntity.getTte() + "\",\n" +
                "    \"ent\": \"intp65\",\n" +
                "    \"vcn\": \"" + speechEntity.getVcn() + "\",\n" +
                "    \"pitch\": "+speechEntity.getPitch()+",\n" +
                "    \"speed\": "+speechEntity.getSpeed()+"\n" +
                "  },\n" +
                "  \"data\": {\n" +
                "    \"status\": 2,\n" +
                "    \"text\": \"" + Base64.getEncoder().encodeToString(speechEntity.getText().getBytes(StandardCharsets.UTF_8)) + "\"\n" +
                //"    \"text\": \"" + Base64.getEncoder().encodeToString(TEXT.getBytes("UTF-16LE")) + "\"\n" +
                "  }\n" +
                "}";
        webSocketClient.send(requestJson);
        // 等待服务端返回完毕后关闭
        while (!wsCloseFlag) {
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        webSocketClient.close();
        wsCloseFlag = false;

    }
    // 鉴权方法
    @Override
    public  String getAuthUrl() {
        URL url = null;
        Mac mac = null;
        String preStr = null;
        String date = null;
        try {
            url = new URL(hostUrl);
            // 时间
            SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
            format.setTimeZone(TimeZone.getTimeZone("GMT"));
            date = format.format(new Date());
            // 拼接
            preStr = "host: " + url.getHost() + "\n" +
                    "date: " + date + "\n" +
                    "GET " + url.getPath() + " HTTP/1.1";
            // SHA256加密
            mac = Mac.getInstance("hmacsha256");
            SecretKeySpec spec = new SecretKeySpec(APISecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");
            mac.init(spec);
        } catch (Exception e) {
            e.printStackTrace();
        }

        byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));
        // Base64加密
        String sha = Base64.getEncoder().encodeToString(hexDigits);
        // 拼接
        String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", APIKey, "hmac-sha256", "host date request-line", sha);
        // 拼接地址
        HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder().//
                addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8))).//
                addQueryParameter("date", date).//
                addQueryParameter("host", url.getHost()).//
                build();
        return httpUrl.toString();
    }
}
